package org.example.commond.handler.message;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.example.commond.AbstractCmdHandler;
import org.example.component.UserInfo;
import org.example.config.Chat;
import org.example.config.CourierConfig;
import org.example.config.Im;
import org.example.enums.CommandEnum;
import org.example.packets.bean.Group;
import org.example.packets.bean.Message;
import org.example.packets.bean.User;
import org.example.packets.handler.message.ChatReqBody;
import org.example.packets.handler.message.ChatRespBody;
import org.example.packets.handler.user.GroupUser;
import org.example.util.JsonUtil;
import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsResponse;

import java.util.Date;
import java.util.Optional;

@Slf4j
public class ChatReqHandler extends AbstractCmdHandler {

    @Override
    public CommandEnum command() {
        return CommandEnum.COMMAND_CHAT_REQ;
    }

    @Override
    public WsResponse handler(Packet packet, ChannelContext channelContext) {

        User user = UserInfo.user();
        ChatReqBody request = JsonUtil.format(packet, ChatReqBody.class);
        Date date = new Date();
        request.setDate(DateUtil.formatDate(date));
        request.setTimestamp(DateUtil.formatTime(date));

        if (CollUtil.isNotEmpty(request.getFiles())) {
            request.getFiles().forEach(x -> {
                if (!x.getUrl().startsWith("https") && !x.getUrl().startsWith("http")) {
                    x.setUrl(CourierConfig.get().getFileUrl() + x.getUrl());
                }
            });
        }

        Message message = BeanUtil.copyProperties(request, Message.class);
        message.setId(ObjectUtil.defaultIfNull(request.get_id(), IdUtil.getSnowflake().nextIdStr()));
        message.setSystem(ObjectUtil.defaultIfNull(message.getSystem(), false));
        message.setSenderId(user.getId());
        message.setDeleted(false);
        message.setSaved(true);
        message.setDistributed(true);
        message.setSeen(false);

        Group group = UserInfo.group(message.getRoomId());
        if (group.getIsFriend() && !Boolean.TRUE.equals(message.getSystem())) {
            // 看看自己有没有拉黑
            Optional<GroupUser> first = group.getUsers().stream().filter(x -> x.getId().equals(user.getId()) && Boolean.TRUE.equals(x.getBlack())).findFirst();
            if (first.isPresent()) {
                message.setFailure(true);
                message.setReceiver(user.getId());

                String msg = "您已将对方加入黑名单,解除后重试";

                ChatReqBody chatReqBody = ChatReqBody.buildSystem(message.getRoomId(), user.getId(), msg, user.getId());
                WsRequest wsRequest = WsRequest.fromText(JSON.toJSONString(chatReqBody, SerializerFeature.DisableCircularReferenceDetect), Im.CHARSET);
                handler(wsRequest, channelContext);
            } else {
                // 看看对方有没有拉黑
                Optional<GroupUser> next = group.getUsers().stream().filter(x -> !x.getId().equals(user.getId()) && Boolean.TRUE.equals(x.getBlack())).findFirst();
                if (next.isPresent()) {
                    message.setFailure(true);
                    message.setReceiver(user.getId());

                    String msg = "对方已将您加入黑名单";

                    ChatReqBody chatReqBody = ChatReqBody.buildSystem(message.getRoomId(), user.getId(), msg, user.getId());
                    WsRequest wsRequest = WsRequest.fromText(JSON.toJSONString(chatReqBody, SerializerFeature.DisableCircularReferenceDetect), Im.CHARSET);
                    handler(wsRequest, channelContext);
                }
            }

        }

        message.setSendTime(System.currentTimeMillis());

        ChatRespBody response = BeanUtil.copyProperties(message, ChatRespBody.class);

        // 发送给群组用户
        Chat.sendToGroup(response, group);

        // 消息缓存至redis
        messageService.putGroupMessage(message);

        // 更新群组最后一条信息
        groupService.updateLastMessage(message);

//        log.info("发送消息入库: " + timer.intervalRestart());
        return null;
    }
}
